// eslint-disable-next-line no-unused-vars
const { fromJS, Map, is, List, set, Set, Range } = require('immutable');

// 1.fromJS()
// 作用：将一个js数据转换为Immutable类型的数据。
// fromJS(value, converter)
// 简介：value是要转变的数据，converter是要做的操作。第二个参数可不填，默认情况会将数组准换为List类型，将对象转换为Map类型，其余不做操作。
console.log(fromJS({a: 1}));
console.log(fromJS([1, 2, 3]));


// 2.toJS()
// 作用：将一个Immutable数据转换为JS类型的数据。
// 用法：value.toJS()
const obj = Map({a: 1}).toJS()
console.log(obj);


// 3.is()
// 作用：对两个对象进行比较。
// 用法：is(map1,map2)
// 简介：和js中对象的比较不同，在js中比较两个对象比较的是地址，但是在Immutable中比较的是这个对象hashCode和valueOf，只要两个对象的hashCode相等，值就是相同的，避免了深度遍历，提高了性能。
const map1 = Map({ a: 1, b: 1, c: 1 })
const map2 = Map({ a: 1, b: 1, c: 1 })
console.log(map1 === map2);
console.log(Object.is(map1, map2));
console.log(is(map1, map2));


// 4.List 和 Map
// 创建 List() 和 Map()
// 作用：创建一个新的包含value的List/Map对象
const map1 = Map({a: 1, b: {c: 2}})
const list1 = List([1, 2, 3, {a: 1}])
console.log(map1, list1);

// 判断
// List.isList() 和 Map.isMap()
// 作用：判断一个数据结构是不是List/Map类型
console.log(Map.isMap(map1));
console.log(List.isList(list1));

// 长度
// 作用：获取List/Map的长度
console.log(map1.size);
console.log(list1.size);


// 5. set && setIn
// set 设置 `第一层` key、index的值
const map2 = map1.set('a', 2)
console.log(map2.toJS(), map1.toJS());
const list2 = list1.set(2, 'a')
console.log(list2.toJS(), list1.toJS());
// setIn 设置深层结构中某属性的值
console.log(map1.setIn(['b', 'c'], 3).toJS(), map1.toJS());
console.log(list1.setIn([3, 'a'], 4).toJS(), list1.toJS());


// 6. get && getIn 同上
console.log(map1.get('a'));
console.log(map1.getIn(['b', 'c']));


// 7. delete && deleteIn 同上
console.log(map1.delete('a').toJS(), map1.toJS());
console.log(map1.deleteIn(['b', 'c']).toJS());


// 8. update && updateIn
// 稍微有些区别, 第二个参数为回调函数, 返回一个新的值, 来更新值, 然后赋值给一个新的变量, 原数据依然保不变
console.log(map1.update('a', val => val + 1).toJS(), map1.toJS());
console.log(map1.updateIn(['b', 'c'], val => val + 1).toJS(), map1.toJS());


// 9. clear 清除所有的数据
console.log(map1.clear().toJS());


// 10. merge && mergeDeep
// 作用：浅合并，新数据与旧数据对比，旧数据中不存在的属性直接添加，就数据中已存在的属性用新数据中的覆盖
const map1 = Map({a: 1, b: {c: 2, e: 3}})
const map2 = Map({a: 2, b: {c: 3, d: 4}})
console.log(map1.merge(map2).toJS());

// mergeDeep 深合并, 对于数组/对象中的数据进行合并
const map1 = Map({a: 100, b: 200, c: {o: 230, w: 10} })
const map2 = Map({a: 10, y: 200, c: {w: 100} })
console.log(map1.mergeDeep(map2).toJS());


// 11. 数组方法  map list
const list1 = List([1, 2, 3, 4])
console.log(list1.filter(item => item >= 3).toJS());
const map1 = Map({a: 1, b: {c: 2}})
console.log(map1.filter(item => item !== 1).toJS());


// 12. grounpBy
// 作用：对数据进行分组
const listOfMaps = List([
  Map({ v: 0 }),
  Map({ v: 1 }),
  Map({ v: 1 }),
  Map({ v: 0 }),
  Map({ v: 2 })
])
console.log(listOfMaps.groupBy(val => val.get('v')).toJS());


// 13. Set
// 将一个数据去重并且转换为 immutable 类型数据
console.log(Set([1, 2, 3, 1]).toJS()); // [1, 2, 3]


// 14. Range
// 返回一个从`start`（包含）到（包含）的数字的Seq.Indexed `end` ，由组成`step`，`start`默认为0、1`step`和`end`无穷大。当`start`等于时`end`，返回空范围。
console.log(Range().toJS()); // [ 0, 1, 2, 3, ... ]
console.log(Range(10)); // [ 10, 11, 12, 13, ... ]
console.log(Range(10, 15).toJS()); // [ 10, 11, 12, 13, 14 ]
console.log(Range(10, 30, 5).toJS()); // [ 10, 15, 20, 25 ]
console.log(Range(30, 10, 5).toJS()); // [ 30, 25, 20, 15 ]
console.log(Range(30, 30, 5).toJS()); // []
